package com.recommender;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import javax.xml.bind.ParseConversionEvent;

import Neighborhood.Neighborhood;
import com.jweight.JImageComponent;

import com.model.DataModel;
import com.model.ProbabilisticDataModel;

public class ProbabilityBaseRecommender  extends StructuredContextRecommender implements Recommender{
	
	public ProbabilisticDataModel genericmodel;
	ArrayList<JImageComponent> 	allelements=new ArrayList<JImageComponent>();
	//public ArrayList<JImage> result=new ArrayList<JImage>();
	private ArrayList<String> contextVariables;
	private HashMap<String, Double> weightValMap=new HashMap<String, Double>();
	
	@Override
	public Map<Integer, Double> getRecommendations(
			HashMap<String, String> contextMap, String keyword, long userID,
			DataModel datamodel, Neighborhood neighborhood) {
		System.out.println("inside recommender");
		return getRecommendations(contextMap, keyword, datamodel);
	}
	public Map<Integer,Double> getRecommendations(HashMap<String, String> contextMap,String keyword,DataModel datamodel) {
		ResultSet tuples=null;
		JImageComponent element;
		LinkedHashMap<Integer, Double> imageResultsMap=new LinkedHashMap<Integer, Double>();
		genericmodel=(ProbabilisticDataModel)datamodel;
		contextVariables=genericmodel.getContextVariablesList();
		/*for(int i=0;i<contextVariables.size();i++){
			setWeightValMap(contextVariables.get(i),33.0);
		}*/	
		//String[] contextVariables=genericmodel.getContextVariables();
		try {
			tuples=genericmodel.getContextDetails(keyword);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try{		
			while(tuples.next()){
				String val1;
				element=new JImageComponent();
				for (int i=0;i<contextVariables.size();i++) {
					String s=contextVariables.get(i);
					element.setContextMap(s, tuples.getString(s));
				}			
				val1=tuples.getString("ImageID");
				element.setImage(val1);
			
				allelements.add(element);			
			}		
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println("Error in reading result");
		}
		try {
			tuples=genericmodel.jgetWeightVal();

		} catch (Exception e) {
			System.out.println("Error in geting weight values result");

			// TODO: handle exception
		}
		try {
			while(tuples.next()){
				
				//element=new JImage();
				for (int i=0;i<contextVariables.size()+1;i++) {
					String context=contextVariables.get(i);
					setWeightValMap(context, Double.parseDouble(tuples.getString(context)));
				}			
							
			}		

		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("Error in reading weidht values");
		}
		
		setProbabilityVal(contextMap);			
		calWeight(genericmodel.result);		
		getrankedArray(genericmodel.result);
		for(int i=0;i<genericmodel.result.size();i++){
			int imagename=Integer.parseInt(genericmodel.result.get(i).getImage());
			imageResultsMap.put(imagename,genericmodel.result.get(i).getWeigthVal());
		}
		for(int i=0;i<genericmodel.result.size();i++){
			System.out.println(genericmodel.result.get(i).getImage()+"   "+i+"   "+ genericmodel.result.get(i).getWeigthVal());
		}
		
		return imageResultsMap;

	}
	public void setProbabilityVal(HashMap<String, String> contextMap){
		String nextImage="",currentImage="";	
		int j=0;
		ArrayList<JImageComponent> temp=new ArrayList<JImageComponent>();	
		for(int i=0;i<allelements.size();i++){
			currentImage=allelements.get(i).getImage();				
				temp.add(allelements.get(i));
							
				j=i+1;
				while(j<allelements.size()){
				
					nextImage=allelements.get(j).getImage();		
					
					if(nextImage.equals(currentImage)){
					
						temp.add(allelements.get(j));
						allelements.get(j).setImage("null");						
					}
					j++;					
				}
				for(int x=0;x<contextVariables.size();x++){
					calProbability(temp,contextMap.get(contextVariables.get(x).toLowerCase()),x);
				}
				
				if(temp.get(0).getImage()!="null"){
					genericmodel.result.add(temp.get(0));
				}
				temp.clear();		
		}	
	}
	public void calProbability (ArrayList<JImageComponent>temp ,String context,int index){
		int val=0;
		double ProbabilityValue=0;		
		
		for(int x=0;x<temp.size();x++){
			if(context.equals(temp.get(x).getContextValueFromMap(contextVariables.get(index)))){
				++val;
			}	
		}
		if(val>temp.size()){
			val=temp.size();
		}		
		ProbabilityValue=(double)val/temp.size();
		
		
		for(int i=0;i<temp.size();i++){
			temp.get(i).setcontextProbabilityMap(contextVariables.get(index), ProbabilityValue);		
			//System.out.println(temp.get(i).getImage()+" "+temp.get(i).getcontextProbabilityValueFromMap(contextVariables.get(index)));
		}
		val=0;
		ProbabilityValue=0;		
	}

	public void getrankedArray(ArrayList<JImageComponent> elements){
		JImageComponent ele1=new JImageComponent();
		JImageComponent ele2=new JImageComponent();
		for (int i = 1; i < elements.size(); i++){
		      int j = i;
		      ele1=elements.get(j);	     
		      double B = elements.get(i).getWeigthVal();
		      while ((j > 0) && (elements.get(j-1).getWeigthVal() < B)){
		    	  ele2=elements.get(j-1);
					elements.set(j, ele2);	    	 
		        j--;
		      }
		      elements.set(j, ele1);	      
		}
		for(int i=0;i<elements.size();i++){
			if(elements.get(i).getWeigthVal()<=0){
				try {
					elements.remove(i);
					i--;
				} catch (Exception e) {
					// TODO: handle exception
				}
			}
		}		
	}
	public void calWeight(ArrayList<JImageComponent>element){	
		double totalWeigth=0;
		for(int i=0;i<element.size();i++){
			for(int j=0;j<contextVariables.size();j++){			
				totalWeigth=(element.get(i).getcontextProbabilityValueFromMap(contextVariables.get(j))*(getWeightValueFromMap(contextVariables.get(j))))+totalWeigth;
			}		
			element.get(i).setWeigthVal(totalWeigth);
			totalWeigth=0;
		}			
	}

	public void setWeightValMap(String contextVariable,Double weightValue)
	{
		weightValMap.put(contextVariable, weightValue);
		
	}
	public Double getWeightValueFromMap(String contextVarible)
	{
		return weightValMap.get(contextVarible);
	}
	
	
}
